use std::{
    any::{Any, TypeId},
    collections::HashMap,
    sync::Arc,
};

use mf_core::{config::ForgeConfig, event::{Event, EventHandler}, middleware::MiddlewareStack, types::Extensions, Content};
use price_rules::loader::RulesLoaderExt;

use super::ProjectProfile;

/// 业务数据源表，key 为数据源标识，value 为任意类型的共享引用
pub type DataSourceMap = HashMap<String, Arc<dyn Any + Send + Sync>>;

/// 额外产物存储器
///
/// 该结构用于在引导流程中暂存任意类型的扩展数据，最终随产物一起返回。
pub(crate) struct ExtraStore {
    values: HashMap<TypeId, Box<dyn Any + Send + Sync>>,
}

impl ExtraStore {
    /// 创建新的存储器实例
    pub(crate) fn new() -> Self {
        Self { values: HashMap::new() }
    }

    /// 以类型 ID 为键插入数据
    pub(crate) fn insert<T>(
        &mut self,
        value: T,
    ) where
        T: Any + Send + Sync + 'static,
    {
        self.values.insert(TypeId::of::<T>(), Box::new(value));
    }

    /// 获取指定类型的数据引用
    pub(crate) fn get<T>(&self) -> Option<&T>
    where
        T: Any + Send + Sync + 'static,
    {
        self.values.get(&TypeId::of::<T>()).and_then(|v| (&**v).downcast_ref::<T>())
    }

    /// 消耗存储器并返回内部 HashMap
    pub(crate) fn into_inner(self) -> HashMap<TypeId, Box<dyn Any + Send + Sync>> {
        self.values
    }
}

/// 引导阶段最终产物集合
///
/// 该结构聚合了项目画像、ModuForge 扩展、元数据、规则加载器、数据源以及额外产品，
/// 供上层在创建运行时对象时直接使用。
///
/// # 重构后的设计
///
/// Bootstrap 系统负责完整的应用初始化，包括：
/// - 业务配置（extensions, rules, data_sources, metadata）
/// - 事件处理（event_handlers）
/// - 中间件（middleware_stack）
/// - 性能配置（ForgeConfig: 包含 history_limit、并发数、队列大小、监控等）
pub struct BootstrapArtifacts {
    profile: ProjectProfile,
    extensions: Vec<Extensions>,
    metadata: HashMap<String, String>,
    rule_loader: Arc<dyn RulesLoaderExt>,
    data_sources: DataSourceMap,
    extras: HashMap<TypeId, Box<dyn Any + Send + Sync>>,

    /// 事件处理器列表
    event_handlers: Vec<Arc<dyn EventHandler<Event> + Send + Sync>>,

    /// 中间件栈
    middleware_stack: Option<MiddlewareStack>,

    /// Forge 性能配置（包含 history_limit、并发数、队列大小、监控等）
    forge_config: Option<ForgeConfig>,
    content: Content,
}

impl BootstrapArtifacts {
    /// 构造函数，仅在上下文完成后调用
    pub(crate) fn new(
        profile: ProjectProfile,
        extensions: Vec<Extensions>,
        metadata: HashMap<String, String>,
        rule_loader: Arc<dyn RulesLoaderExt>,
        data_sources: DataSourceMap,
        extras: HashMap<TypeId, Box<dyn Any + Send + Sync>>,
        event_handlers: Vec<Arc<dyn EventHandler<Event> + Send + Sync>>,
        middleware_stack: Option<MiddlewareStack>,
        forge_config: Option<ForgeConfig>,
        content: Content
    ) -> Self {
        Self { profile, extensions, metadata, rule_loader, data_sources, extras, event_handlers, middleware_stack, forge_config,content }
    }

    /// 获取项目画像
    pub fn profile(&self) -> &ProjectProfile {
        &self.profile
    }

    /// 获取扩展列表（不可变引用）
    pub fn extensions(&self) -> &[Extensions] {
        &self.extensions
    }

    /// 消耗产物并返回扩展列表
    pub fn into_extensions(self) -> Vec<Extensions> {
        self.extensions
    }

    /// 获取附加元数据
    pub fn metadata(&self) -> &HashMap<String, String> {
        &self.metadata
    }

    /// 获取规则加载器共享指针
    pub fn rule_loader(&self) -> Arc<dyn RulesLoaderExt> {
        Arc::clone(&self.rule_loader)
    }

    /// 获取指定类型数据源
    pub fn data_source<T>(
        &self,
        key: &str,
    ) -> Option<Arc<T>>
    where
        T: Any + Send + Sync + 'static,
    {
        self.data_sources.get(key).cloned().and_then(|ds| ds.downcast::<T>().ok())
    }

    /// 判断数据源是否存在
    pub fn contains_data_source(
        &self,
        key: &str,
    ) -> bool {
        self.data_sources.contains_key(key)
    }

    /// 获取额外产物
    pub fn extra<T>(&self) -> Option<&T>
    where
        T: Any + Send + Sync + 'static,
    {
        self.extras.get(&TypeId::of::<T>()).and_then(|v| (&**v).downcast_ref::<T>())
    }

    /// 获取事件处理器列表
    pub fn event_handlers(&self) -> &[Arc<dyn EventHandler<Event> + Send + Sync>] {
        &self.event_handlers
    }

    /// 获取中间件栈
    pub fn middleware_stack(&self) -> Option<&MiddlewareStack> {
        self.middleware_stack.as_ref()
    }

    /// 获取 Forge 配置
    pub fn forge_config(&self) -> Option<&ForgeConfig> {
        self.forge_config.as_ref()
    }

    /// 添加扩展到产物中
    ///
    /// 用于在 Bootstrap 完成后动态添加扩展（如规则引擎扩展）
    pub fn add_extension(
        &mut self,
        extension: Extensions,
    ) {
        self.extensions.push(extension);
    }

    /// 添加多个扩展到产物中
    pub fn add_extensions<I>(
        &mut self,
        extensions: I,
    ) where
        I: IntoIterator<Item = Extensions>,
    {
        self.extensions.extend(extensions);
    }

    /// 使用 Bootstrap 产物构建运行时
    ///
    /// Bootstrap 包含所有配置，可以直接构建运行时。
    ///
    /// # 返回值
    /// * `ForgeResult<AnyRuntime>` - 构建好的运行时实例
    ///
    /// # 示例
    /// ```rust
    /// let artifacts = loader.bootstrap(profile).await?;
    /// let runtime = artifacts.build_runtime().await?;
    /// ```
    pub async fn build_runtime(&self) -> mf_core::ForgeResult<mf_core::runtime::AnyRuntime> {
        use mf_core::ForgeRuntimeBuilder;

        // 1. 创建 Builder，如果有 ForgeConfig 就使用它
        let mut builder =
            if let Some(config) = &self.forge_config { ForgeRuntimeBuilder::new().with_config(config.clone()) } else { ForgeRuntimeBuilder::new() };

        // 2. 设置扩展（从 SchemaProvider 和 PluginProvider 收集）
        builder = builder.extensions(self.extensions.clone());

        // 3. 设置事件处理器
        for handler in &self.event_handlers {
            builder = builder.event_handler(handler.clone());
        }

        // 4. 设置中间件栈（如果有）
        if let Some(_stack) = &self.middleware_stack {
            // 注意：ForgeRuntimeBuilder 可能没有 middleware_stack 方法
            // 如果需要，可以通过 Extension 的方式注入
            // 这里暂时跳过，等待后续实现
        }
        builder = builder.content(self.content.clone());

        // 5. 构建运行时
        // 注意：history_limit 已经在 ForgeConfig.history.max_entries 中配置
        builder.build().await
    }
}
